#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
typedef long long ll;
using namespace std;
struct mark{
    bool over;
    int point;
    int pre;
    ll cnt;
};
vector<int> list[200005];
int color[200005];
vector<mark> color_tree[200005];
ll cnt[200005];
ll DFS(int a) {
    int length=list[a].size();
    mark mar;
    int col=color[a];
    int pre=color_tree[col].size()-1;
    int tree_len=pre+1;
    while (color_tree[col][pre].over) pre=color_tree[col][pre].pre;
    mar.point=a;
    mar.pre=pre;
    mar.over=false;
    mar.cnt=0;
    color_tree[col].push_back(mar);
    if (length==0) {
        cnt[a]=0;
        color_tree[col][tree_len].over=true;
        return 1;
    }
    ll nex_all=0;
    ll tmp;
    for (int i=0; i<length; i++) {
        tmp=DFS(list[a][i]);
        nex_all+=tmp;
    }
    cnt[a]=nex_all;
    color_tree[col][tree_len].over=true;
    return nex_all+1;
}
int main() {
    int n;
    int x,y;
    int cas=1;
    while (cin>>n) {
        int all_col=0;
        for (int i=1; i<=n; i++) {
            scanf("%d", &color[i]);
            if (color[i]>all_col) all_col=color[i];
        }
        for (int i=0; i<=n; i++) {
            list[i].clear();
        }
        mark mar;
        mar.point=0;
        mar.cnt=0;
        mar.pre=0;
        mar.over=false;
        for (int i=0; i<=all_col; i++) {
            color_tree[i].clear();
            color_tree[i].push_back(mar);
        }
        for (int i=1; i<n; i++) {
            scanf("%d%d", &x, &y);
            if (x>y) swap(x,y);
            list[x].push_back(y);
        }
        DFS(1);
        cnt[0]=cnt[1]+1;
        ll res=0;
        ll tmp;
        ll coll=0;
/*        cout<<"haha ";
        for (int i=0; i<=n; i++) cout<<cnt[i]<<' ';
        cout<<endl;*/
        for (int i=1; i<=all_col; i++) {
//            cout<<"---"<<i<<"---"<<endl;
            /*for (int j=0; j<color_tree[i].size(); j++) {
                mar=color_tree[i][j];
                cout<<mar.point<<' '<<mar.pre<<' '<<mar.cnt<<endl;
            }*/
            if (color_tree[i].size()<2) continue;
            coll++;
            int st=color_tree[i].size()-1;
            while (st>=0) {
                mar=color_tree[i][st];
                tmp=cnt[mar.point]-color_tree[i][st].cnt;
//                cout<<cnt[mar.point]<<" cnt: "<<mar.cnt<<endl;
//                cout<<"tmp: "<<tmp<<' ';
//                cout<<tmp*(tmp-1)/2<<endl;
                res+=tmp*(tmp-1)/2;
                color_tree[i][mar.pre].cnt+=cnt[mar.point]+1;
//                cout<<mar.point<<' '<<mar.pre<<' '<<mar.cnt<<endl;
                if (mar.point==1) break;
                st--;
            }
        }
        tmp=n;
        res=(coll*tmp*(tmp-1)/2-res);
        cout<<"Case #"<<cas<<": "<<res<<endl;
        cas++;
    }
    return 0;
}
